﻿using System.Collections.Generic;
using System.Security.AccessControl;
using System.Linq;
using System.Text;

namespace System.IO
{
    public class InMemoryDirectoryInfo : InMemoryFileSystemEntryInfo, IDirectoryInfo
    {
        public InMemoryDirectoryInfo(InMemoryFileSystemStore store, InMemoryFileSystemEntryProperties entry) : base(store, entry)
        {
        }

        public InMemoryDirectoryInfo(InMemoryFileSystemStore store, string name) : base(store, name)
        {
        }

        public override string Name
        {
            get { return FullName; }
        }

        public IDirectoryInfo CreateSubdirectory(string path)
        {
            return CreateSubdirectory(path, null);
        }

        public IDirectoryInfo CreateSubdirectory(string path, DirectorySecurity directorySecurity)
        {
            return Store.CreateDirectory(LongPathTools.Instance.Combine(FullName, path));
        }

        public void Create()
        {
            Create(null);
        }

        public void Create(DirectorySecurity directorySecurity)
        {
            if (directorySecurity!= null) throw new NotImplementedException();
            Store.CreateDirectory(FullName);
        }

        public DirectorySecurity GetAccessControl()
        {
            throw new System.NotImplementedException();
        }

        public DirectorySecurity GetAccessControl(AccessControlSections includeSections)
        {
            throw new System.NotImplementedException();
        }

        public void SetAccessControl(DirectorySecurity directorySecurity)
        {
            throw new System.NotImplementedException();
        }

        public IFileInfo[] GetFiles(string searchPattern)
        {
            return GetFiles(searchPattern, SearchOption.TopDirectoryOnly);
        }

        public IFileInfo[] GetFiles(string searchPattern, SearchOption searchOption)
        {
            return Store.GetFiles(FullName, searchOption).Where(t => t.Name.MatchesWildcard(searchPattern)).Cast<IFileInfo>().ToArray();
        }

        public IFileInfo[] GetFiles()
        {
            return GetFiles("*");
        }

        public IDirectoryInfo[] GetDirectories()
        {
            return GetDirectories("*");
        }

        public IFileSystemInfo[] GetFileSystemInfos(string searchPattern)
        {
            return GetFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly);
        }

        public IFileSystemInfo[] GetFileSystemInfos(string searchPattern, SearchOption searchOption)
        {
            return Store.GetFileSystemEntries(FullName, searchOption).ToArray();
        }

        public IFileSystemInfo[] GetFileSystemInfos()
        {
            return GetFileSystemInfos("*");
        }

        public IDirectoryInfo[] GetDirectories(string searchPattern)
        {
            return GetDirectories(searchPattern, SearchOption.TopDirectoryOnly);
        }

        public IDirectoryInfo[] GetDirectories(string searchPattern, SearchOption searchOption)
        {
            return Store.GetSubdirectories(FullName, searchOption).Cast<IDirectoryInfo>().ToArray();
        }

        public IEnumerable<IDirectoryInfo> EnumerateDirectories()
        {
            return EnumerateDirectories("*");
        }

        public IEnumerable<IDirectoryInfo> EnumerateDirectories(string searchPattern)
        {
            return EnumerateDirectories(searchPattern, SearchOption.TopDirectoryOnly);
        }

        public IEnumerable<IDirectoryInfo> EnumerateDirectories(string searchPattern, SearchOption searchOption)
        {
            return Store.GetSubdirectories(FullName, searchOption)
                .Where(t => t.FullName.MatchesWildcard(searchPattern));
        }

        public IEnumerable<IFileInfo> EnumerateFiles()
        {
            return EnumerateFiles("*");
        }

        public IEnumerable<IFileInfo> EnumerateFiles(string searchPattern)
        {
            return EnumerateFiles(searchPattern, SearchOption.TopDirectoryOnly);
        }

        public IEnumerable<IFileInfo> EnumerateFiles(string searchPattern, SearchOption searchOption)
        {
            return Store.GetFiles(FullName, searchOption)
                .Where(t => t.FullName.MatchesWildcard(searchPattern)).Cast<IFileInfo>();
        }

        public IEnumerable<IFileSystemInfo> EnumerateFileSystemInfos()
        {
            return EnumerateFileSystemInfos("*");
        }

        public IEnumerable<IFileSystemInfo> EnumerateFileSystemInfos(string searchPattern)
        {
            return EnumerateFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly);
        }

        public IEnumerable<IFileSystemInfo> EnumerateFileSystemInfos(string searchPattern, SearchOption searchOption)
        {
            return Store.GetFileSystemEntries(FullName, searchOption)
                .Where(t => t.FullName.MatchesWildcard(searchPattern));
        }

        public void MoveTo(string destDirName)
        {
            Store.MoveDirectory(FullName, destDirName);
        }

        public void Delete(bool recursive)
        {
            Store.DeleteDirectory(FullName, recursive);
        }

        public IDirectoryInfo Parent
        {
            get { return Store.GetDirectoryInfo(LongPathTools.Instance.GetParentDirectory(FullName)); }
        }

        public IDirectoryInfo Root
        {
            get { return Store.GetDirectoryInfo(LongPathTools.Instance.GetPathRoot(FullName)); }
        }
    }
}